const jwt = require('jsonwebtoken');
const gravatar = require('gravatar')

const User = require('../models/users')
const HandAccount = require('../models/handAccount')
const { secret } = require('../config');

class UserCtl {
    async find(ctx) {
        const { per_page = 10 } = ctx.query;
        const page = Math.max(ctx.query.page * 1, 1) - 1;
        const perPage = Math.max(per_page * 1, 1);
        ctx.body = await User
            .find({ username: new RegExp(ctx.query.q) })
            .limit(perPage).skip(page * perPage);
    }

    async findById(ctx) {
        const { fields = '' } = ctx.query
        const SelectFields = fields.split(';').filter(f => f).map(f => '+' + f).join('')
        const user = await User.findById(ctx.params.id).select(SelectFields)
        if (!user) ctx.throw(404, '用户不存在')
        ctx.body = user
    }

    async create(ctx) {
        const { email } = ctx.request.body
        let user = await User.findOne({ email })
        if (user) ctx.throw(409, '用户名已存在')
        let new_user = ctx.request.body
        new_user.avatar = gravatar.url(new_user.email, { s: '100', r: 'x', d: 'retro' }, false)
        const { _id } = await new User(new_user).save()
        ctx.body = await User.findById(_id)
    }

    async checkOwner(ctx, next) {
        if (ctx.state.user._id !== ctx.params.id) ctx.throw(403, '没有权限')
        await next()
    }

    async update(ctx) {
        const user = await User.findByIdAndUpdate(ctx.params.id, ctx.request.body)
        if (!user) ctx.throw(404, '用户不存在')
        ctx.body = await User.findById(ctx.params.id)
    }

    async delete(ctx) {
        ctx.status = 204
        const user = await User.findByIdAndRemove(ctx.params.id, ctx.request.body)
        if (!user) ctx.throw(404, '用户不存在')
        ctx.body = {}
    }

    async login(ctx) {
        const user = await User.findOne(ctx.request.body)
        if (!user) ctx.throw(401, '用户名或者密码不正确')
        const { _id, name } = user
        const token = jwt.sign({ _id, name }, secret, { expiresIn: '3d' })
        let res = { user, token }
        ctx.body = res
    }

    async listFollowing(ctx) {
        const user = await User.findById(ctx.params.id).select('+following').populate('following')
        if (!user) ctx.throw(404)
        ctx.body = user.following
    }

    async listFollowers(ctx) {
        const users = await User.find({ following: ctx.params.id })
        ctx.body = users
    }

    async listFollowingTopics(ctx) {
        const user = await User.findById(ctx.params.id).select('+followingTopics').populate('followingTopics')
        if (!user) ctx.throw(404, '用户不存在')
        ctx.body = user.followingTopics
    }


    // 检查用户是否存在中间件
    async checkUserExist(ctx, next) {
        const user = User.findById(ctx.params.id)
        if (!user) ctx.throw(404, '用户不存在')
        await next()
    }

    async follow(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+following')
        if (!me.following.map(id => id.toString()).includes(ctx.params.id)) {
            me.following.push(ctx.params.id)
            me.save()
        }
        ctx.status = 204
    }

    async unfollow(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+following')
        const index = me.following.map(id => id.toString()).indexOf(ctx.params.id)
        if (index > -1) {
            me.following.splice(index, 1).save()
        }
        ctx.status = 204
    }

    async followTopic(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+followingTopic')
        if (!me.followingTopics.map(id => id.toString()).includes(ctx.params.id)) {
            me.followingTopics.push(ctx.params.id).save()
        }
        ctx.status = 204
    }

    async unfollowTopic(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+followingTopic')
        const index = me.followingTopics.map(id => id.toString()).indexOf(ctx.params.id)
        if (index > -1) {
            me.following.splice(index, 1).save()
        }
        ctx.status = 204
    }

    async listHandAccount(ctx) {
        let isPrivate = ctx.query.isPrivate
        if (isPrivate === undefined) {
            isPrivate === false
        } else {
            isPrivate = JSON.parse(ctx.query.isPrivate)
        }

        const id = ctx.params.id
        console.log(isPrivate, id)

        ctx.body = await HandAccount.find({ owner: id }).find({ isOpen: !isPrivate })
    }

    async likeHandAccount(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+likeHandAccounts')
        if (!me.likeHandAccounts.map(id => id.toString()).includes(ctx.params.id)) {
            me.followingTopics.push(ctx.params.id).save()
        }
        ctx.status = 204
    }

    async dislikeHandAccount(ctx) {
        const me = await User.findById(ctx.state.user._id).select('+likeHandAccounts')
        const index = me.likeHandAccounts.map(id => id.toString()).indexOf(ctx.params.id)
        if (index > -1) {
            me.following.splice(index, 1).save()
        }
        ctx.status = 204
    }
}

module.exports = new UserCtl()